package com.kpmg.datalake.web.controller;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.kpmg.datalake.common.controller.BaseController;
import com.kpmg.datalake.common.enums.ResultCodeEnum;
import com.kpmg.datalake.common.enums.UseOrDelEnum;
import com.kpmg.datalake.common.exception.BusinessException;
import com.kpmg.datalake.common.utils.AssertUtil;
import com.kpmg.datalake.common.utils.ExceptionUtil;
import com.kpmg.datalake.common.vo.ServerResponse;
import com.kpmg.datalake.operatelog.annotation.OptLog;
import com.kpmg.datalake.operatelog.enums.LogTypeEnum;
import com.kpmg.datalake.schedule.enums.ScheduleStatusEnum;
import com.kpmg.datalake.schedule.model.ScheduleJob;
import com.kpmg.datalake.schedule.model.ScheduleJobLog;
import com.kpmg.datalake.schedule.service.IScheduleJobLogService;
import com.kpmg.datalake.schedule.service.IScheduleJobService;
import com.kpmg.datalake.schedule.service.IScheduleMangerService;
import com.kpmg.datalake.schedule.vo.ScheduleJobLogVO;
import com.kpmg.datalake.schedule.vo.ScheduleJobVO;
import java.util.List;
import javax.annotation.Resource;
import org.quartz.CronExpression;
import org.quartz.SchedulerException;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * 任务调度 前端控制器
 * </p>
 *
 * @author azhao6
 * @since 2018-08-09
 */
@RestController
@RequestMapping("/schedule/scheduleJob")
public class ScheduleJobController extends BaseController {

  //CronExpression.isValidExpression(supplyBase.getFileCron()) 校验

  @Resource
  private IScheduleMangerService scheduleMangerService;
  @Resource
  private IScheduleJobService scheduleJobService;
  @Resource
  private IScheduleJobLogService scheduleJobLogService;

  @GetMapping("/getAllJobs")
  public List<ScheduleJob> getAllJobs() throws SchedulerException {

    return scheduleMangerService.getAllJob();
  }

  /**
   * 分页获取任务信息
   *
   * @param scheduleJobVO scheduleJobVO
   * @return ServerResponse
   */
  @PostMapping("/getPageByScheduleJob")
  public ServerResponse<Page<ScheduleJob>> getPageByScheduleJob(
      @RequestBody ScheduleJobVO<ScheduleJob> scheduleJobVO) {
    try {
      ScheduleJob scheduleJob = scheduleJobVO.getScheduleJob();
      Page<ScheduleJob> page = scheduleJobVO.getPage();
      scheduleJob.setDelInd(UseOrDelEnum.USE.getIntCode());
      page = scheduleJobService.selectPage(page, new EntityWrapper<>(scheduleJob));
      return super.doSuccess(page);
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }

  /**
   * 分页获取任务日志信息
   *
   * @param scheduleJobLogVO scheduleJobLogVO
   * @return ServerResponse
   */
  @PostMapping("/getPageByScheduleJobLog")
  public ServerResponse<Page<ScheduleJobLog>> getPageByScheduleJobLog(
      @RequestBody ScheduleJobLogVO<ScheduleJobLog> scheduleJobLogVO) {
    try {
      ScheduleJobLog scheduleJobLog = scheduleJobLogVO.getScheduleJobLog();
      Page<ScheduleJobLog> page = scheduleJobLogVO.getPage();
      EntityWrapper<ScheduleJobLog> scheduleJobLogEntityWrapper = new EntityWrapper<>(
          scheduleJobLog);
      scheduleJobLogEntityWrapper.orderBy("begin_Time", false);
      page = scheduleJobLogService.selectPage(page, scheduleJobLogEntityWrapper);
      return super.doSuccess(page);
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }

  /**
   * 启动任务
   *
   * @param scheduleJob scheduleJob
   * @return ServerResponse
   */
  @PostMapping("/startJob")
  @OptLog(logType = LogTypeEnum.SYSTEM, module = "system", description = "后台任务启动")
  public ServerResponse<String> startJob(@RequestBody ScheduleJob scheduleJob) {
    try {
      AssertUtil.assertNotEmpty(scheduleJob.getJobId(), ResultCodeEnum.CODE4038.getDisplay());
      scheduleJob = scheduleJobService.selectById(scheduleJob.getJobId());
      if (scheduleJob == null) {
        throw new BusinessException(ResultCodeEnum.CODE4000.getCode(), ResultCodeEnum.CODE4000.getDisplay());
      }
      scheduleJob.setJobStatus(ScheduleStatusEnum.RUNNING.getCode());
      scheduleJobService.updateById(scheduleJob);
      scheduleMangerService.addJob(scheduleJob);
      return super.doSuccess(ResultCodeEnum.CODE0000.getDisplay());
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }

  /**
   * 停止任务
   * @param scheduleJob scheduleJob
   * @return ServerResponse
   */
  @PostMapping("/stopJob")
  public ServerResponse<String> stopJob(@RequestBody ScheduleJob scheduleJob) {
    try {
      AssertUtil.assertNotEmpty(scheduleJob.getJobId(), ResultCodeEnum.CODE4038.getDisplay());
      scheduleJob = scheduleJobService.selectById(scheduleJob.getJobId());
      if (scheduleJob == null) {
        throw new BusinessException(ResultCodeEnum.CODE4000.getCode(), ResultCodeEnum.CODE4000.getDisplay());
      }
      scheduleJob.setJobStatus(ScheduleStatusEnum.STOP.getCode());
      scheduleJobService.updateById(scheduleJob);
      scheduleMangerService.deleteJob(scheduleJob);
      return super.doSuccess(ResultCodeEnum.CODE0000.getDisplay());
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }

  /**
   *  根据id获取任务明细
   * @param scheduleJob scheduleJob
   * @return ServerResponse
   */
  @PostMapping("/getJobDetailById")
  public ServerResponse<ScheduleJob> getJobDetailById(@RequestBody ScheduleJob scheduleJob) {
    try {
      AssertUtil.assertNotEmpty(scheduleJob.getJobId(), ResultCodeEnum.CODE4038.getDisplay());
      scheduleJob = scheduleJobService.selectById(scheduleJob.getJobId());
      if (scheduleJob == null) {
        throw new BusinessException(ResultCodeEnum.CODE4000.getCode(), ResultCodeEnum.CODE4000.getDisplay());
      }
      return super.doSuccess(scheduleJob);
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }

  /**
   * 更新任务
   * @param scheduleJob scheduleJob
   * @return ServerResponse
   */
  @PostMapping("/updateJob")
  public ServerResponse<String> updateJob(@RequestBody ScheduleJob scheduleJob) {
    try {
      AssertUtil.assertNotEmpty(scheduleJob.getJobId(), ResultCodeEnum.CODE4038.getDisplay());
      ScheduleJob scheduleJobOld = scheduleJobService.selectById(scheduleJob.getJobId());
      if (scheduleJobOld == null) {
        throw new BusinessException(ResultCodeEnum.CODE4000.getCode(), ResultCodeEnum.CODE4000.getDisplay());
      }
      if (!scheduleMangerService.validateBeanOrClass(scheduleJob.getJobAction())) {
        throw new BusinessException(ResultCodeEnum.CODE4040.getCode(), "任务动作不合法，后台找不到对应的执行动作");
      }
      scheduleJobService.updateById(scheduleJob);
      scheduleMangerService.addJob(scheduleJob);
      return super.doSuccess("更新成功");
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }

  /**
   * 新增任务
   * @param scheduleJob scheduleJob
   * @return ServerResponse
   */
  @PostMapping("/addJob")
  public ServerResponse<String> addJob(@RequestBody ScheduleJob scheduleJob) {
    try {
      AssertUtil.assertNotEmpty(scheduleJob.getJobName());
      AssertUtil.assertNotEmpty(scheduleJob.getJobGroup());
      AssertUtil.assertNotEmpty(scheduleJob.getJobAction());
      if (!StringUtils.isEmpty(scheduleJob.getJobCron()) && !CronExpression
          .isValidExpression(scheduleJob.getJobCron())) {
        throw new BusinessException(ResultCodeEnum.CODE4039.getCode(), "任务执行周期不合法");
      }
      if (!scheduleMangerService.validateBeanOrClass(scheduleJob.getJobAction())) {
        throw new BusinessException(ResultCodeEnum.CODE4040.getCode(), "任务动作不合法，后台找不到对应的执行动作");
      }
      scheduleJobService.insert(scheduleJob);
      scheduleMangerService.addJob(scheduleJob);
      return super.doSuccess("新增成功");
    } catch (Exception e) {
      return ExceptionUtil.getExceptionMsg(e);
    }
  }
}

